import axios from 'axios';
import querystring from 'querystring';
import { Dialog, Toast } from 'vant';
import createRouter from '@/router/index';
import createStore from '@/store/index';

const store = createStore();

// console.log('process.env', process.env);
const isFront = process.env.VUE_APP_ENV === 'front';
const isClient = process.env.VUE_APP_ENV === 'client';
const env = process.env.VUE_APP_ENV;
let baseURL = '';
if (process.env.VUE_NODE_ENV == 'development') {
  baseURL = process.env.VUE_APP_LOCAL_AXIOS_HOST;
}
if (process.env.VUE_NODE_ENV == 'tm') {
  baseURL = process.env.VUE_APP_TM_AXIOS_HOST;
}

if (process.env.VUE_NODE_ENV == 'testmall') {
  baseURL = process.env.VUE_APP_TESTMALL_AXIOS_HOST;
}

if (process.env.VUE_NODE_ENV == 'production') {
  baseURL = process.env.VUE_APP_BUILD_AXIOS_HOST;
}
baseURL += process.env.VUE_APP_PUBLIC_PATH;
// console.log('_axios baseURL', baseURL);
const _axios = axios.create({
  baseURL: `${baseURL}/api/`,
  timeout: 6000,
  withCredentials: true
});

const requestMap = new Map();
_axios.interceptors.request.use(config => {
  // 防重复提交，针对购买、定投、赎回等功能
  const index = config.url.indexOf('?');
  const urlStr = index > 0 ? config.url.substr(0, index) : config.url;
  const preventReq = [
    'dz-mall/r/account/getFundInfo',
    'dz-mall/r/order/asset/buy',
    'dz-mall/r/order/asset/redeem',
    'dz-mall/r/order/asset/preRedeem',
    'dz-mall/r/order/finan/buy',
    'dz-mall/r/order/finan/redeem',
    'dz-mall/r/order/fund/buy',
    'dz-mall/r/order/fund/fundTransform',
    'dz-mall/r/order/fund/redeem',
    'dz-mall/r/order/fund/addPlan'
  ].indexOf(urlStr) > -1;
  if (preventReq) {
    const keyString = querystring.stringify({
      url: config.url,
      method: config.method,
      ...config.data
    });
    if (requestMap.get(keyString)) {
    // 取消当前请求
      config.cancelToken = new axios.CancelToken((cancel) => {
        cancel(`101,请不要重复提交请求`);
      });
    }
    requestMap.set(keyString, true);
    Object.assign(config, { _keyString: keyString });
  }
  // 客户端发起的所有请求都需要加上请求头frontOpStation参数
  if (isClient || isFront) {
    const opStation = sessionStorage.getItem('opStation') || '';
    config.headers.frontOpStation = opStation;
  }

  // if (!isFront) {
  config.headers.accept = 'json';
  // }

  if (config.loading) {
    store.commit('setRequestCount');
    store.commit('setLoadingState', true);
  }
  return config;
}, error => {
  store.commit('setLoadingState', false);
  console.log(`${env} axios request err`, error);
  return Promise.reject(error);
});

_axios.interceptors.response.use(response => {
  // 重置requestMap
  const { config } = response;
  if (config._keyString) {
    requestMap.set(config._keyString, false);
  }

  if (config.loading) {
    store.commit('setResponseCount');
  }
  if (store.state.requestCount > 0 && store.state.requestCount === store.state.responseCount) {
    store.commit('setLoadingState', false);
    // 重置请求数，响应数
    store.commit('resetRequestCount');
    store.commit('resetResponseCount');
  }
  if (response.status >= 400 && response.data.errors.length) {
    let message = '';
    response.data.errors.forEach(error => {
      message += `${error.message}\n`;
    });
    return Promise.reject(new Error(`500,${env} axios status > 400 err. ${message}`));
  }
  return response;
}, (error) => {
  store.commit('setLoadingState', false);

  let message = `${error.message}`;
  if (error.config) {
    message += `, url: ${error.config.url}`;
  }
  return Promise.reject(new Error(`${message}`));
});

function checkStatus(response) {
  // 如果状态码正常，则直接返回数据
  if (response && (response.status === 200 || response.status === 304 || response.status === 400)) {
    return response;
  }
  return {
    status: -404,
    msg: '接口请求异常'
  };
}

function checkCode(response) {
  // 如果code异常，可提示用户错误信息
  if (response.status === -404) {
    Dialog({
      title: '异常情况',
      message: response.msg
    });
    return;
  }

  // 错误码-9998为挂维护模式，统一拦截重定向到维护页面
  if (response.data && response.data.returnCode == '-9998') {
    const router = createRouter();
    const redirectUrl = router.history.pending ? router.history.pending.fullPath : router.history.current.fullPath;
    sessionStorage.setItem('maintenanceUrl', redirectUrl);
    window.location.replace(`${window.location.origin}/dz-mall/otc/front/maintenance`);
    return;
  }

  // 错误码-9999为未登录，不报错，跳转到首页登录
  if (response.data && response.data.returnCode === '-9999') {
    // 未登录，跳转登录页
    const router = createRouter();
    const redirectUrl = router.history.pending ? router.history.pending.fullPath : router.history.current.fullPath;
    sessionStorage.setItem('redirectUrl', redirectUrl);
    router.push({
      path: `${process.env.VUE_APP_PUBLIC_PATH}/login`
    });
    return;
  }
  return response.data;
}

export default {
  async request(url, options = { }) {
    const defaultOptions = {
      method: 'get',
      data: {}
    };
    options = { ...defaultOptions, ...options };
    const { data } = options;
    if (options.method !== 'postBody' && data) {
      const searchstring = querystring.stringify(data);
      url += searchstring ? `?${searchstring}` : '';
    }
    if (options.method === 'postBody') {
      options.method = 'post';
      options.headers = {
        'Content-Type': 'application/json;charset=UTF-8'
      };
    }

    const params = {
      url,
      ...options
    };

    // 服务端，传递cookie
    if ((!isClient || !isFront) && options.cookie) {
      params.headers = params.headers || {};
      params.headers.Cookie = options.cookie;
    }

    // console.log('_axios', url, data, params);
    return _axios(params)
      .then(response => {
        return checkStatus(response);
      })
      .then(response => {
        return checkCode(response);
      })
      .catch(err => {
        const message = err.message || '';
        const code = message.split(',')[0];
        const info = message.split(',')[1];
        console.log(message, code, info);
        if (code == '101') {
          // 重复提交时，提示
          Toast(info);
          return {};
        }
        Toast('网络异常或接口错误，请稍后重试');
        // return Promise.resolve({ returnCode: code, returnInfo: '网络错误，请重试' });
      });
  },
  async post(url, data = {}, options = {}) {
    options.method = 'post';
    options.data = data;
    return this.request(url, options);
  },
  async get(url, data = {}, options = {}) {
    options.data = data;
    return this.request(url, options);
  },
  async postBody(url, data = {}, options = {}) {
    options.method = 'postBody';
    options.data = data;
    options.headers = { 'Content-Type': 'application/json;charset=UTF-8' };
    return this.request(url, options);
  },
};